<template>
  <div class="html-demo">
    <h2 class="section-title">HTML5 特性演示</h2>
    
    <div class="demo-grid">
      <!-- Canvas 和 SVG -->
      <div class="demo-card group">
        <div class="demo-header">
          <h3>Canvas 和 SVG</h3>
          <button class="code-toggle" @click="toggleCode('canvas')">
            {{ showCode.canvas ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.canvas">
            <pre class="code-viewer"><code>// Canvas 示例
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

// 绘制渐变背景
const gradient = ctx.createLinearGradient(0, 0, 300, 200)
gradient.addColorStop(0, '#ff6b6b')
gradient.addColorStop(1, '#4ecdc4')
ctx.fillStyle = gradient
ctx.fillRect(0, 0, 300, 200)

// 绘制动画图形
function drawAnimatedShape() {
  ctx.clearRect(0, 0, 300, 200)
  ctx.beginPath()
  ctx.arc(150, 100, 50, 0, Math.PI * 2)
  ctx.fillStyle = '#ff6b6b'
  ctx.fill()
}

// SVG 示例
&lt;svg width="300" height="200"&gt;
  &lt;defs&gt;
    &lt;linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="100%"&gt;
      &lt;stop offset="0%" style="stop-color:#ff6b6b"/&gt;
      &lt;stop offset="100%" style="stop-color:#4ecdc4"/&gt;
    &lt;/linearGradient&gt;
  &lt;/defs&gt;
  &lt;rect x="10" y="10" width="280" height="180" 
        fill="url(#gradient)" rx="10" ry="10"/&gt;
  &lt;circle cx="150" cy="100" r="50" 
          fill="#ff6b6b" opacity="0.8"/&gt;
  &lt;text x="150" y="100" text-anchor="middle" 
        fill="white" font-size="20"&gt;SVG&lt;/text&gt;
&lt;/svg&gt;</code></pre>
          </div>
          <div class="demo-preview">
            <div class="demo-description">
              <p>这个示例展示了HTML5的Canvas和SVG：</p>
              <ul>
                <li>Canvas：用于动态绘制图形，支持像素级操作</li>
                <li>SVG：用于绘制矢量图形，支持缩放而不失真</li>
                <li>两者都支持渐变、动画等高级特性</li>
              </ul>
            </div>
            <div class="canvas-svg-demo">
              <div class="canvas-container">
                <canvas ref="canvas" width="300" height="200" class="canvas"></canvas>
                <div class="canvas-controls">
                  <button @click="drawGradient">绘制渐变</button>
                  <button @click="startAnimation">开始动画</button>
                  <button @click="stopAnimation">停止动画</button>
                </div>
              </div>
              <div class="svg-container">
                <svg width="300" height="200" class="svg">
                  <defs>
                    <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="100%">
                      <stop offset="0%" style="stop-color:#ff6b6b"/>
                      <stop offset="100%" style="stop-color:#4ecdc4"/>
                    </linearGradient>
                  </defs>
                  <rect x="10" y="10" width="280" height="180" 
                        fill="url(#gradient)" rx="10" ry="10"/>
                  <circle cx="150" cy="100" r="50" 
                          fill="#ff6b6b" opacity="0.8"/>
                  <text x="150" y="100" text-anchor="middle" 
                        fill="white" font-size="20">SVG</text>
                </svg>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 拖放操作 -->
      <div class="demo-card group">
        <div class="demo-header">
          <h3>拖放操作</h3>
          <button class="code-toggle" @click="toggleCode('drag')">
            {{ showCode.drag ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.drag">
            <pre class="code-viewer"><code>// HTML结构
&lt;div 
  class="drag-source"
  draggable="true"
  @dragstart="onDragStart"
&gt;
  拖动我
&lt;/div&gt;

&lt;div 
  class="drop-target"
  @dragover.prevent
  @drop="onDrop"
&gt;
  放置区域
&lt;/div&gt;

// JavaScript代码
const onDragStart = (event) => {
  event.dataTransfer.setData('text', '已拖放的元素')
}

const onDrop = (event) => {
  event.preventDefault()
  const data = event.dataTransfer.getData('text')
  event.target.textContent = data
}</code></pre>
          </div>
          <div class="demo-preview">
            <div class="demo-description">
              <p>这个示例展示了HTML5的拖放功能：</p>
              <ul>
                <li>使用 <code>draggable</code> 属性使元素可拖动</li>
                <li>通过 <code>dragstart</code> 和 <code>drop</code> 事件处理拖放</li>
                <li>使用 <code>dataTransfer</code> 传递数据</li>
                <li>支持自定义拖放效果和样式</li>
              </ul>
            </div>
            <div ref="dragSource" class="drag-source" draggable="true" @dragstart="onDragStart">
              拖动我
            </div>
            <div ref="dropTarget" class="drop-target" @dragover.prevent @drop="onDrop">
              放置区域
            </div>
          </div>
        </div>
      </div>

      <!-- Web Storage -->
      <div class="demo-card group">
        <div class="demo-header">
          <h3>Web Storage</h3>
          <button class="code-toggle" @click="toggleCode('storage')">
            {{ showCode.storage ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.storage">
            <pre class="code-viewer"><code>// 存储数据
localStorage.setItem('key', value)

// 读取数据
const data = localStorage.getItem('key')

// 删除数据
localStorage.removeItem('key')

// 清空所有数据
localStorage.clear()</code></pre>
          </div>
          <div class="demo-preview">
            <div class="demo-description">
              <p>这个示例展示了HTML5的Web Storage功能：</p>
              <ul>
                <li>使用 <code>localStorage</code> 持久化存储数据</li>
                <li>支持存储、读取、删除操作</li>
                <li>数据在浏览器关闭后仍然保留</li>
                <li>适用于存储用户偏好设置等</li>
              </ul>
            </div>
            <div class="storage-demo">
              <div class="input-group">
                <input 
                  v-model="storageData" 
                  placeholder="输入要存储的数据"
                  @keyup.enter="saveToStorage"
                  class="storage-input"
                >
                <div class="storage-controls">
                  <button class="storage-btn save" @click="saveToStorage">
                    <i class="fas fa-save"></i>
                    保存数据
                  </button>
                  <button class="storage-btn load" @click="loadFromStorage">
                    <i class="fas fa-download"></i>
                    读取数据
                  </button>
                  <button class="storage-btn clear" @click="clearStorage">
                    <i class="fas fa-trash"></i>
                    清除数据
                  </button>
                </div>
              </div>
              <div v-if="storedData" class="stored-data">
                <div class="stored-data-header">已存储的数据:</div>
                <div class="stored-data-content">{{ storedData }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 音频处理 -->
      <div class="demo-card group">
        <div class="demo-header">
          <h3>音频处理</h3>
          <button class="code-toggle" @click="toggleCode('audio')">
            {{ showCode.audio ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.audio">
            <pre class="code-viewer"><code>// 创建音频上下文
const audioContext = new AudioContext()

// 加载音频文件
const response = await fetch(audioUrl)
const arrayBuffer = await response.arrayBuffer()
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer)

// 创建音频源
const source = audioContext.createBufferSource()
source.buffer = audioBuffer

// 连接到输出设备并播放
source.connect(audioContext.destination)
source.start()</code></pre>
          </div>
          <div class="demo-preview">
            <div class="demo-description">
              <p>这个示例展示了HTML5的音频处理功能：</p>
              <ul>
                <li>支持上传和播放音频文件</li>
                <li>使用 <code>AudioContext</code> 处理音频</li>
                <li>可以控制音频的播放和暂停</li>
                <li>支持音频可视化等高级功能</li>
              </ul>
            </div>
            <div class="audio-demo">
              <div class="upload-area">
                <input 
                  type="file" 
                  class="file-input" 
                  accept="audio/*"
                  @change="handleAudioUpload"
                >
                <p class="upload-text">点击或拖放音频文件到此处</p>
              </div>
              <audio v-if="audioUrl" :src="audioUrl" controls class="media-player"></audio>
            </div>
          </div>
        </div>
      </div>

      <!-- Web Worker -->
      <div class="demo-card group">
        <div class="demo-header">
          <h3>Web Worker</h3>
          <button class="code-toggle" @click="toggleCode('worker')">
            {{ showCode.worker ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.worker">
            <pre class="code-viewer"><code>// 创建Worker
const worker = new Worker('worker.js')

// 发送消息给Worker
worker.postMessage({ count: 1000000 })

// 接收Worker的消息
worker.onmessage = (event) => {
  console.log('计算结果:', event.data)
}

// Worker代码 (worker.js)
self.onmessage = (event) => {
  const { count } = event.data
  let result = 0
  
  for (let i = 0; i < count; i++) {
    result += Math.sqrt(i) * Math.sin(i)
  }
  
  self.postMessage(result.toFixed(2))
}</code></pre>
          </div>
          <div class="demo-preview">
            <div class="demo-description">
              <p>这个示例展示了HTML5的Web Worker功能：</p>
              <ul>
                <li>在后台线程执行耗时计算</li>
                <li>不阻塞主线程的UI响应</li>
                <li>通过消息机制与主线程通信</li>
                <li>适用于复杂计算和数据处理</li>
              </ul>
            </div>
            <div class="worker-demo">
              <div class="controls">
                <button @click="startWorker">开始计算</button>
              </div>
              <div v-if="workerResult" class="result">
                计算结果: {{ workerResult }}
              </div>
              <div v-if="errors.worker" class="error-message">
                {{ errors.worker }}
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 语义化标签 -->
      <div class="demo-card group">
        <div class="demo-header">
          <h3>语义化标签</h3>
          <button class="code-toggle" @click="toggleCode('semantic')">
            {{ showCode.semantic ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.semantic">
            <pre class="code-viewer"><code>&lt;header&gt;
  &lt;h1&gt;标题&lt;/h1&gt;
&lt;/header&gt;
&lt;nav&gt;
  &lt;ul&gt;
    &lt;li&gt;导航项1&lt;/li&gt;
    &lt;li&gt;导航项2&lt;/li&gt;
  &lt;/ul&gt;
&lt;/nav&gt;
&lt;main&gt;
  &lt;article&gt;
    &lt;h2&gt;文章标题&lt;/h2&gt;
    &lt;p&gt;文章内容...&lt;/p&gt;
  &lt;/article&gt;
&lt;/main&gt;
&lt;footer&gt;
  &lt;p&gt;页脚内容&lt;/p&gt;
&lt;/footer&gt;</code></pre>
          </div>
          <div class="demo-preview">
            <div class="demo-description">
              <p>这个示例展示了HTML5的语义化标签：</p>
              <ul>
                <li>使用 <code>&lt;header&gt;</code>, <code>&lt;nav&gt;</code>, <code>&lt;main&gt;</code>, <code>&lt;article&gt;</code>, <code>&lt;footer&gt;</code> 等标签</li>
                <li>提高文档的可读性和可访问性</li>
              </ul>
            </div>
            <div class="semantic-demo">
              <header>
                <h1>示例标题</h1>
              </header>
              <nav>
                <ul>
                  <li>导航项1</li>
                  <li>导航项2</li>
                </ul>
              </nav>
              <main>
                <article>
                  <h2>文章标题</h2>
                  <p>文章内容...</p>
                </article>
              </main>
              <footer>
                <p>页脚内容</p>
              </footer>
            </div>
          </div>
        </div>
      </div>

      <!-- 表单控件 -->
      <div class="demo-card group">
        <div class="demo-header">
          <h3>表单控件</h3>
          <button class="code-toggle" @click="toggleCode('form')">
            {{ showCode.form ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.form">
            <pre class="code-viewer"><code>&lt;input type="date"&gt;
&lt;input type="color"&gt;
&lt;input type="range"&gt;</code></pre>
          </div>
          <div class="demo-preview">
            <div class="demo-description">
              <p>这个示例展示了HTML5的表单控件：</p>
              <ul>
                <li>使用 <code>&lt;input type="date"&gt;</code> 选择日期</li>
                <li>使用 <code>&lt;input type="color"&gt;</code> 选择颜色</li>
                <li>使用 <code>&lt;input type="range"&gt;</code> 选择范围</li>
              </ul>
            </div>
            <div class="form-demo">
              <input type="date" class="form-input" v-model="dateValue" />
              <input type="color" class="form-input" v-model="colorValue" />
              <input type="range" min="0" max="100" class="form-input" v-model="rangeValue" />
              <div class="form-result">
                <p>选择的日期: {{ dateValue }}</p>
                <p>选择的颜色: {{ colorValue }}</p>
                <p>选择的范围: {{ rangeValue }}</p>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 多媒体元素 -->
      <div class="demo-card group">
        <div class="demo-header">
          <h3>多媒体元素</h3>
          <button class="code-toggle" @click="toggleCode('media')">
            {{ showCode.media ? '隐藏代码' : '查看代码' }}
          </button>
        </div>
        <div class="demo-content">
          <div class="code-block" v-if="showCode.media">
            <pre class="code-viewer"><code>&lt;video src="video.mp4" controls&gt;&lt;/video&gt;
&lt;audio src="audio.mp3" controls&gt;&lt;/audio&gt;</code></pre>
          </div>
          <div class="demo-preview">
            <div class="demo-description">
              <p>这个示例展示了HTML5的多媒体元素：</p>
              <ul>
                <li>使用 <code>&lt;video&gt;</code> 嵌入视频</li>
                <li>使用 <code>&lt;audio&gt;</code> 嵌入音频</li>
              </ul>
            </div>
            <div class="media-demo">
              <div class="upload-area">
                <input 
                  type="file" 
                  class="file-input" 
                  accept="video/*"
                  @change="handleVideoUpload"
                >
                <p class="upload-text">点击或拖放视频文件到此处</p>
              </div>
              <video v-if="videoUrl" :src="videoUrl" controls class="media-player"></video>
              <div class="upload-area">
                <input 
                  type="file" 
                  class="file-input" 
                  accept="audio/*"
                  @change="handleAudioUpload"
                >
                <p class="upload-text">点击或拖放音频文件到此处</p>
              </div>
              <audio v-if="audioUrl" :src="audioUrl" controls class="media-player"></audio>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

const showCode = ref({
  canvas: false,
  drag: false,
  storage: false,
  audio: false,
  worker: false,
  video: false,
  semantic: false,
  form: false,
  media: false
})

const canvas = ref(null)
const dragSource = ref(null)
const dropTarget = ref(null)

const storageData = ref('')
const storedData = ref('')

const audioUrl = ref('')

const workerResult = ref('')
const worker = ref(null)
const errors = ref({
  worker: ''
})

// 视频播放相关
const videoPlayer = ref(null)
const videoUrl = ref('')
const isPlaying = ref(false)
const currentTime = ref(0)
const duration = ref(0)
const volume = ref(1)
const playbackRate = ref('1.0')
const progress = ref(0)
const supportsPiP = ref(false)

const dateValue = ref('')
const colorValue = ref('#000000')
const rangeValue = ref(50)

const animationFrame = ref(null)
const isAnimating = ref(false)

const toggleCode = (section) => {
  showCode.value[section] = !showCode.value[section]
}

const onDragStart = (event) => {
  event.dataTransfer.setData('text', '已拖放的元素')
}

const onDrop = (event) => {
  event.preventDefault()
  const data = event.dataTransfer.getData('text')
  event.target.textContent = data
}

const saveToStorage = () => {
  if (!storageData.value) return
  localStorage.setItem('demo-data', storageData.value)
  storedData.value = storageData.value
  storageData.value = ''
}

const loadFromStorage = () => {
  storedData.value = localStorage.getItem('demo-data') || ''
}

const clearStorage = () => {
  localStorage.removeItem('demo-data')
  storedData.value = ''
  storageData.value = ''
}

const handleAudioUpload = (event) => {
  const file = event.target.files[0]
  if (file) {
    audioUrl.value = URL.createObjectURL(file)
  }
}

const startWorker = () => {
  try {
    if (worker.value) {
      worker.value.terminate()
    }

    const workerCode = `
      self.onmessage = (event) => {
        const count = 1000000
        let result = 0
        
        for (let i = 0; i < count; i++) {
          result += Math.sqrt(i) * Math.sin(i)
        }
        
        self.postMessage(result.toFixed(2))
      }
    `
    const blob = new Blob([workerCode], { type: 'application/javascript' })
    const workerUrl = URL.createObjectURL(blob)
    worker.value = new Worker(workerUrl)

    worker.value.onmessage = (event) => {
      workerResult.value = event.data
      URL.revokeObjectURL(workerUrl)
    }

    worker.value.onerror = (error) => {
      errors.value.worker = `Worker错误: ${error.message}`
      URL.revokeObjectURL(workerUrl)
    }

    worker.value.postMessage({})
  } catch (error) {
    errors.value.worker = `Worker错误: ${error.message}`
  }
}



// 视频文件处理
const handleVideoUpload = (event) => {
  const file = event.target.files[0]
  if (file) {
    if (videoUrl.value) {
      URL.revokeObjectURL(videoUrl.value)
    }
    videoUrl.value = URL.createObjectURL(file)
  }
}

// 视频事件处理
const handleTimeUpdate = () => {
  if (videoPlayer.value) {
    currentTime.value = videoPlayer.value.currentTime
    progress.value = (currentTime.value / duration.value) * 100
  }
}

const handleDurationChange = () => {
  if (videoPlayer.value) {
    duration.value = videoPlayer.value.duration
  }
}

const handlePlay = () => {
  isPlaying.value = true
}

const handlePause = () => {
  isPlaying.value = false
}

const drawGradient = () => {
  const ctx = canvas.value.getContext('2d')
  const gradient = ctx.createLinearGradient(0, 0, 300, 200)
  gradient.addColorStop(0, '#ff6b6b')
  gradient.addColorStop(1, '#4ecdc4')
  ctx.fillStyle = gradient
  ctx.fillRect(0, 0, 300, 200)
}

const drawAnimatedShape = () => {
  const ctx = canvas.value.getContext('2d')
  const time = Date.now() * 0.001
  
  ctx.clearRect(0, 0, 300, 200)
  ctx.beginPath()
  ctx.arc(
    150 + Math.cos(time) * 30,
    100 + Math.sin(time) * 30,
    30 + Math.sin(time * 2) * 10,
    0,
    Math.PI * 2
  )
  ctx.fillStyle = '#ff6b6b'
  ctx.fill()
  
  if (isAnimating.value) {
    animationFrame.value = requestAnimationFrame(drawAnimatedShape)
  }
}

const startAnimation = () => {
  if (!isAnimating.value) {
    isAnimating.value = true
    drawAnimatedShape()
  }
}

const stopAnimation = () => {
  isAnimating.value = false
  if (animationFrame.value) {
    cancelAnimationFrame(animationFrame.value)
  }
}

onMounted(() => {
  drawGradient()
  if (videoPlayer.value) {
    videoPlayer.value.addEventListener('timeupdate', handleTimeUpdate)
    videoPlayer.value.addEventListener('durationchange', handleDurationChange)
    videoPlayer.value.addEventListener('play', handlePlay)
    videoPlayer.value.addEventListener('pause', handlePause)
    
    // 检查是否支持画中画模式
    supportsPiP.value = document.pictureInPictureEnabled
  }
})

onUnmounted(() => {
  if (worker.value) {
    worker.value.terminate()
  }
  if (audioUrl.value) {
    URL.revokeObjectURL(audioUrl.value)
  }
  if (videoPlayer.value) {
    videoPlayer.value.removeEventListener('timeupdate', handleTimeUpdate)
    videoPlayer.value.removeEventListener('durationchange', handleDurationChange)
    videoPlayer.value.removeEventListener('play', handlePlay)
    videoPlayer.value.removeEventListener('pause', handlePause)
  }
  if (videoUrl.value) {
    URL.revokeObjectURL(videoUrl.value)
  }
  stopAnimation()
})
</script>

<style scoped>
.html-demo {
  padding: 2rem;
}

.section-title {
  font-size: 2.5rem;
  margin-bottom: 2rem;
  text-align: center;
  background: linear-gradient(45deg, #00ff88, #00a8ff);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.demo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
}

.demo-card {
  background: rgba(255, 255, 255, 0.05);
  border-radius: 10px;
  padding: 1.5rem;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.demo-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
}

.demo-header h3 {
  margin: 0;
  font-size: 1.5rem;
  color: #00ff88;
}

.code-toggle {
  background: rgba(0, 255, 136, 0.1);
  border: 1px solid rgba(0, 255, 136, 0.3);
  color: #00ff88;
  padding: 0.5rem 1rem;
  border-radius: 5px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.code-toggle:hover {
  background: rgba(0, 255, 136, 0.2);
}

.demo-content {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.code-block {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 5px;
  overflow: hidden;
}

.demo-preview {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.demo-description {
  color: var(--text-color);
}

.demo-description code {
  background: rgba(0, 0, 0, 0.2);
  padding: 0.2rem 0.4rem;
  border-radius: 3px;
  font-family: 'Fira Code', monospace;
}

.controls {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.controls button {
  background: rgba(0, 255, 136, 0.1);
  border: 1px solid rgba(0, 255, 136, 0.3);
  color: #00ff88;
  padding: 0.5rem 1rem;
  border-radius: 5px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.controls button:hover {
  background: rgba(0, 255, 136, 0.2);
}

canvas {
  width: 100%;
  height: 200px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 5px;
}

.drag-source {
  background: rgba(0, 255, 136, 0.2);
  padding: 1rem;
  border-radius: 5px;
  cursor: move;
  text-align: center;
  margin-bottom: 1rem;
  transition: all 0.3s ease;
}

.drop-target {
  background: rgba(255, 255, 255, 0.1);
  padding: 2rem;
  border-radius: 5px;
  border: 2px dashed rgba(0, 255, 136, 0.3);
  text-align: center;
  transition: all 0.3s ease;
}

.drop-target:hover {
  background: rgba(255, 255, 255, 0.15);
  border-color: rgba(0, 255, 136, 0.5);
}

.code-viewer {
  width: 100%;
  margin: 0;
  padding: 1rem;
  background: transparent;
  color: #b8e0d2;
  font-family: 'Fira Code', monospace;
  font-size: 0.9rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-x: auto;
}

.code-viewer code {
  display: block;
  width: 100%;
}

@media (max-width: 768px) {
  .html-demo {
    padding: 1rem;
  }

  .section-title {
    font-size: 2rem;
  }

  .demo-grid {
    grid-template-columns: 1fr;
  }

  .code-block {
    font-size: 0.8rem;
  }
}

.storage-demo {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.input-group {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.storage-input {
  width: 100%;
  padding: 0.8rem 1.2rem;
  font-size: 1rem;
  color: var(--text-color);
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(0, 255, 136, 0.2);
  border-radius: 8px;
  transition: all 0.3s ease;
}

.storage-input:focus {
  outline: none;
  border-color: rgba(0, 255, 136, 0.5);
  box-shadow: 0 0 0 2px rgba(0, 255, 136, 0.1);
}

.storage-input::placeholder {
  color: rgba(255, 255, 255, 0.3);
}

.storage-controls {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

.storage-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.8rem 1.2rem;
  font-size: 0.9rem;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 1px solid transparent;
}

.storage-btn i {
  font-size: 1rem;
}

.storage-btn.save {
  background: rgba(0, 255, 136, 0.1);
  border-color: rgba(0, 255, 136, 0.3);
  color: #00ff88;
}

.storage-btn.save:hover {
  background: rgba(0, 255, 136, 0.2);
  border-color: rgba(0, 255, 136, 0.5);
}

.storage-btn.load {
  background: rgba(0, 149, 255, 0.1);
  border-color: rgba(0, 149, 255, 0.3);
  color: #0095ff;
}

.storage-btn.load:hover {
  background: rgba(0, 149, 255, 0.2);
  border-color: rgba(0, 149, 255, 0.5);
}

.storage-btn.clear {
  background: rgba(255, 69, 58, 0.1);
  border-color: rgba(255, 69, 58, 0.3);
  color: #ff453a;
}

.storage-btn.clear:hover {
  background: rgba(255, 69, 58, 0.2);
  border-color: rgba(255, 69, 58, 0.5);
}

.stored-data {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 8px;
  overflow: hidden;
}

.stored-data-header {
  padding: 0.8rem 1.2rem;
  background: rgba(0, 255, 136, 0.1);
  color: #00ff88;
  font-weight: 500;
  border-bottom: 1px solid rgba(0, 255, 136, 0.2);
}

.stored-data-content {
  padding: 1.2rem;
  color: var(--text-color);
  word-break: break-all;
  line-height: 1.5;
}

@media (max-width: 768px) {
  .storage-controls {
    flex-direction: column;
  }
  
  .storage-btn {
    width: 100%;
    justify-content: center;
  }
}

.audio-demo {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.upload-area {
  border: 2px dashed rgba(0, 255, 136, 0.3);
  border-radius: 10px;
  padding: 2rem;
  text-align: center;
  position: relative;
  background: rgba(0, 255, 136, 0.05);
  cursor: pointer;
  transition: all 0.3s ease;
}

.upload-area:hover {
  border-color: rgba(0, 255, 136, 0.5);
  background: rgba(0, 255, 136, 0.1);
}

.file-input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.upload-text {
  color: var(--text-color);
  font-size: 1rem;
}

audio {
  width: 100%;
  border-radius: 5px;
  margin-top: 1rem;
}

.worker-demo {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
}

.result {
  padding: 1rem;
  background: rgba(0, 255, 136, 0.1);
  border-radius: 5px;
  text-align: center;
  width: 100%;
}

.error-message {
  margin-top: 1rem;
  padding: 0.8rem;
  background: rgba(255, 50, 50, 0.1);
  border: 1px solid rgba(255, 50, 50, 0.3);
  border-radius: 5px;
  color: #ff5050;
  font-size: 0.9rem;
  font-family: 'Fira Code', monospace;
  white-space: pre-wrap;
  word-break: break-word;
}

.video-demo {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.video-container {
  position: relative;
  width: 100%;
  background: #000;
  border-radius: 10px;
  overflow: hidden;
  margin-top: 1rem;
}

.video-player {
  width: 100%;
  max-height: 300px;
  background: #000;
}

.custom-controls {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 1rem;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
  opacity: 0;
  transition: opacity 0.3s ease;
}

.video-container:hover .custom-controls {
  opacity: 1;
}

.progress-bar {
  width: 100%;
  height: 4px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 2px;
  cursor: pointer;
  margin-bottom: 0.5rem;
}

.progress {
  height: 100%;
  background: #00ff88;
  border-radius: 2px;
  transition: width 0.1s linear;
}

.control-buttons {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.time-display {
  color: #fff;
  font-family: monospace;
}

.volume-control {
  display: flex;
  align-items: center;
  width: 100px;
}

.volume-control input[type="range"] {
  width: 100%;
  height: 4px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 2px;
  outline: none;
}

select {
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 3px;
  padding: 0.2rem;
}

@media (max-width: 768px) {
  .control-buttons {
    flex-wrap: wrap;
    gap: 0.5rem;
  }
  
  .volume-control {
    width: 60px;
  }
}

.semantic-demo {
  padding: 1rem;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 5px;
}

.form-demo {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.media-demo {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.canvas-svg-demo {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.canvas-container,
.svg-container {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
}

.canvas-controls {
  display: flex;
  gap: 0.5rem;
}

.canvas {
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.svg {
  border-radius: 10px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
</style> 